/*
 * Copyright (c) 2016. For Intelligent Group.
 */

package com.intelligent.mts.da.handler;


import com.intelligent.mts.common.utils.StringUtils;
import com.intelligent.mts.core.dto.SerialNumberDto;
import com.intelligent.mts.core.service.DataSearchService;
import com.intelligent.mts.core.utils.AppConst;
import com.intelligent.mts.da.message.ReceiveMessage;
import com.intelligent.mts.da.utils.ApplicationBeanUtils;
import com.intelligent.mts.da.utils.MessageUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by Julia.Zhou on 2016/07/20.
 */
public class SaveOffLineDataHandler extends ChannelInboundHandlerAdapter {

	public static Logger logger = LoggerFactory.getLogger(SaveOffLineDataHandler.class);
	private DataSearchService dataSearchService;

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		logger.info("reading----" + msg);
		logger.info("Start saving data process.");
		String returnMessage = "";
		ReceiveMessage receiveMessage = (ReceiveMessage) msg;
		String station = receiveMessage.getStationId();
		try{
			this.setService();
			AttributeKey<String> attributeKey = null;
			if (!AttributeKey.exists(AppConst.PRODUCTION_ID)) {
				attributeKey = AttributeKey.newInstance(AppConst.PRODUCTION_ID);
			} else {
				attributeKey = AttributeKey.valueOf(AppConst.PRODUCTION_ID);
			}
			String hs = receiveMessage.getHs();
			if (StringUtils.isBlank(hs)) {
				String productionId = ctx.channel().attr(attributeKey).get();
				if (productionId == null || productionId.isEmpty()){
					logger.error("Please input hs first");
					returnMessage = AppConst.START_OFFLINE_RESP + AppConst.SEPARATOR + station + AppConst.SEPARATOR + AppConst.RESULT_NG + AppConst.END_FLAG;
					ctx.fireChannelRead(returnMessage);
					return;
				}
				productionId = dataSearchService.findHsProductionId(productionId);
				if (StringUtils.isBlank(productionId)) {
					returnMessage = AppConst.START_OFFLINE_RESP + AppConst.SEPARATOR + station + AppConst.SEPARATOR + AppConst.RESULT_NG + AppConst.END_FLAG;
				} else {
					returnMessage = this.saveSN(receiveMessage, productionId);
					returnMessage = AppConst.START_OFFLINE_RESP + AppConst.SEPARATOR + station + AppConst.SEPARATOR + returnMessage  + AppConst.END_FLAG;
				}
			} else {
				String productId = dataSearchService.findProductionIdBySerialValue(hs);
				productId = dataSearchService.findHsProductionId(productId);
				ctx.channel().attr(attributeKey).set(productId);
				if (StringUtils.isBlank(productId)) {
					returnMessage = AppConst.START_OFFLINE_RESP + AppConst.SEPARATOR + station + AppConst.SEPARATOR + AppConst.RESULT_NG + AppConst.END_FLAG;
				} else {
					returnMessage = AppConst.START_OFFLINE_RESP + AppConst.SEPARATOR + station + AppConst.SEPARATOR + AppConst.RESULT_OK + AppConst.END_FLAG;
				}
			}
			//String returnMessage = "2021;OK#";
//			ctx.writeAndFlush(returnMessage);
			ctx.fireChannelRead(returnMessage);
			logger.info("Process finish, return:[{}]", returnMessage);
		} catch (Exception e) {
			returnMessage = AppConst.START_OFFLINE_RESP + AppConst.SEPARATOR + station + AppConst.SEPARATOR + AppConst.RESULT_NG + AppConst.END_FLAG;
//			ctx.writeAndFlush(returnMessage);
			ctx.fireChannelRead(returnMessage);
			logger.info("Process finish, return:[{}]", returnMessage);
			logger.error("Exception found:[{}]", e.getMessage());
			e.printStackTrace();
		}

	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		logger.warn("Unexpected exception from com.intelligent.mts.da.handler " + cause);
		ctx.fireExceptionCaught(cause);
	}

	private String saveSN(ReceiveMessage receiveMessage, String productionId) {
		logger.info("Save sn start.");
		if (receiveMessage.getSnLists() != null && !receiveMessage.getSnLists().isEmpty()) {
			for (String sn : receiveMessage.getSnLists().keySet()) {
				if ( MessageUtils.validateSnIsExistMoresProduction(receiveMessage.getSnLists().get(sn))) {
					logger.error("SerialNunber is exist more production");
					return AppConst.RESULT_NG;
				}

				SerialNumberDto	serialNumberDto1 = dataSearchService.findCondition(productionId, receiveMessage.getStationId(), sn);
				String pn = receiveMessage.getPnLists().get(sn);
				if (serialNumberDto1 != null) {
					serialNumberDto1.setProductionId(productionId);
					serialNumberDto1.setStationId(receiveMessage.getStationId());
					serialNumberDto1.setSerialName(sn);
					serialNumberDto1.setSerialValue(receiveMessage.getSnLists().get(sn));
					serialNumberDto1.setPnValue(pn);
					dataSearchService.updateSerialNumber(serialNumberDto1);
				} else {
					SerialNumberDto serialNumberDto = new SerialNumberDto();
					serialNumberDto.setProductionId(productionId);
					serialNumberDto.setStationId(receiveMessage.getStationId());
					serialNumberDto.setSerialName(sn);
					serialNumberDto.setSerialValue(receiveMessage.getSnLists().get(sn));
					serialNumberDto.setPnValue(pn);
					dataSearchService.createSerialNumber(serialNumberDto);
				}
			}
			logger.info("Save sn finish");
			return AppConst.RESULT_OK;
		} else {
			logger.info("Save sn finish");
			return AppConst.RESULT_NG;
		}

	}

	public void setService() {
		if (dataSearchService == null) {
			dataSearchService = ApplicationBeanUtils.getBean(DataSearchService.class);
		}
	}
}
